package com.example.emqx.config;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * File: MyFilter.java
 * Author: liufudong@szyh-smart.com
 * Date: 2024/9/19
 * Description: MyFilter class.
 * Http 1. 过滤器（Filter）
 * 用途：
 * 过滤器用于对请求和响应进行预处理和后处理。它们在请求到达Servlet之前和响应离开Servlet之后执行。
 * 常用于日志记录、请求修改、响应修改、跨域请求处理等。
 * 工作原理：
 * 过滤器是Servlet规范的一部分，位于Servlet容器中。它们可以对请求进行过滤（如日志记录、身份验证），然后将请求传递给下一个过滤器或目标Servlet。
 * 过滤器也可以修改请求或响应。
 */
@Component
@Slf4j
@WebFilter(urlPatterns = "/")
public class MyFilter implements Filter {
    private String TAG = "MyFilter";

    @Override
    public void init(jakarta.servlet.FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        log.info("{} init", TAG);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 处理请求
        getRequestInfo(servletRequest);
        log.info("{} doFilter", TAG);

        // 包装 HttpServletResponse
        CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) servletResponse);

        // 继续执行下一个过滤器或目标处理器
        filterChain.doFilter(servletRequest, responseWrapper);

        // 获取返回数据
        String responseData = responseWrapper.toString();
        log.info("{} doFilter servletResponse:{}, responseData:{}", TAG,
                ((HttpServletRequest) servletRequest).getRequestURL().toString()
                        + ((HttpServletRequest) servletRequest).getRequestURI().toString(), responseData);

        // 将捕获的响应数据重新写回客户端
        if (responseData != null) {
            servletResponse.getWriter().write(responseData);
        }
    }

    public void getRequestInfo(ServletRequest servletRequest) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        // 获取请求的完整URL（包含协议和主机）
        String requestURL = httpServletRequest.getRequestURL().toString();
        log.debug("requestURL:{}", requestURL);
        // 获取请求的URI（不包含协议和主机）
        String requestURI = httpServletRequest.getRequestURI();
        log.debug("requestURI:{}", requestURI);
        // 获取查询字符串（请求的参数部分）
        String queryString = httpServletRequest.getQueryString();
        log.debug("queryString:{}", queryString);
        // 获取请求方法（GET, POST等）
        String method = httpServletRequest.getMethod();
        log.debug("method:{}", method);
        // 获取请求的主机名
        String host = httpServletRequest.getHeader("Host");
        log.debug("host:{}", host);

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
        log.info("{} destroy", TAG);
    }
}
